﻿/******************************************************************************
 * 【本类功能概述】                                 					      *
 *  版权所有（C）2017-20XX，米兔网络                                         *
 *  保留所有权利。                                                            *
 ******************************************************************************
 *  作者 : <hughjk>
 *  创建时间:2019年6月17日 18:54:26
 *  文件描述:加载缓存处理器
 *****************************************************************************/

using System;
using System.Collections.Generic;
using Object = UnityEngine.Object;
namespace Util
{
    public class LoadCacheBase
    {
        public int Id;
        public LoadCacheMgr m_load;
        public LoadCacheBase(LoadCacheMgr load)
        {
            m_load = load;
        }
    }
    public class LoadCache<T> : LoadCacheBase where T : Object
    {
        private Dictionary<string, T> m_ObjPool = new Dictionary<string, T>();

        private Dictionary<string, List<Action<T>>> m_CacheRequest = new Dictionary<string, List<Action<T>>>();

        public LoadCache(LoadCacheMgr load) : base(load) { }

        //加载到对象
        public void LoadInstantiate(string path, Action<T> CallBack)
        {
            Load(path, (go) =>
            {
                CallBack(Object.Instantiate(go) as T);
            });
        }

        //缓存内存加载
        public void Load(string path, Action<T> CallBack)
        {
            T cobj;
            if (m_ObjPool.TryGetValue(path, out cobj))//有没有在请求加载
            {
                if (cobj)//加载好了
                {
                    CallBack.Invoke(cobj);
                }
                else//没有加载好
                {
                    CacheRequest(path, CallBack);
                }
            }
            else
            {
                //请求加载
                m_ObjPool.Add(path, default(T));
                //缓存请求
                CacheRequest(path, CallBack);
                m_load.LoadAsset(path, (string _path, object asset) =>
                {
                    var zobj = asset as T;
                    if (zobj == null)
                    {
                        m_ObjPool.Remove(_path);
                        debug.log(debug.Level.error_3, "请求加载资源类型(", typeof(T).ToString(), ")与实际加载资源类型(", asset.GetType().ToString(), ")不符合!!!!");
                    }
                    else
                    {
                        m_ObjPool[_path] = zobj;
                    }
                    List<Action<T>> request;
                    if (m_CacheRequest.TryGetValue(_path, out request))
                    {
                        debug.log("加载成功", _path, "需求量:", request.Count);
                        int num = request.Count;
                        for (int i = 0; i < num; i++)
                        {
                            //debug.log(cobj.name);
                            request[i].Invoke(zobj);
                        }
                        m_CacheRequest.Remove(_path);
                    }
                });
            }
        }
        //卸载引用,在下一次GC会完全丢失
        public void Release()
        {
            m_ObjPool.Clear();
            m_CacheRequest.Clear();
        }

        //缓存请求
        private void CacheRequest(string path, Action<T> CallBack)
        {
            List<Action<T>> request;
            if (m_CacheRequest.TryGetValue(path, out request))
            {
                request.Add(CallBack);
            }
            else
            {
                m_CacheRequest.Add(path, new List<Action<T>>() { CallBack });
            }
        }
    }
    public abstract class LoadCacheMgr
    {
        public List<LoadCacheBase> m_LoadCachesAll;
        public LoadCacheMgr()
        {
            m_LoadCachesAll = new List<LoadCacheBase>();
        }

        //是否卸载
        public abstract void Release();

        //加载资源
        public abstract void LoadAsset(string path, Action<string, object> Callbacks);

    }

    //--------------------------------------------------------------------------------------------
    //public class XXX : LoadCacheMgr
    //{
    //    public static XXX Ins { get { return Singleton<XXX>.Instance; } }
    //
    //    public XXX() : base()
    //    {
    //        m_LoadCachesAll.Add(new LoadCache<GameObject>(this));
    //    }
    //
    //    public override void Release()
    //    {
    //        throw new NotImplementedException();
    //    }
    //
    //    public override void LoadAsset(string path, Action<object> Callbacks)
    //    {
    //        throw new NotImplementedException();
    //    }
    //}
}

